package work.parabola.keyboardswitch.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import work.parabola.keyboardswitch.common.PlateConst;
import work.parabola.keyboardswitch.common.ResponseCode;
import work.parabola.keyboardswitch.common.ServerResponse;
import work.parabola.keyboardswitch.dao.*;
import work.parabola.keyboardswitch.pojo.UserSession;
import work.parabola.keyboardswitch.pojo.query.plate.*;
import work.parabola.keyboardswitch.pojo.query.storeswitch.AutoProduceTesterQuery;
import work.parabola.keyboardswitch.pojo.repository.*;
import work.parabola.keyboardswitch.pojo.vo.plate.*;
import work.parabola.keyboardswitch.pojo.vo.storeswitch.StoreSwitchListVo;
import work.parabola.keyboardswitch.service.IPlateService;
import work.parabola.keyboardswitch.service.IStoreSwitchService;
import work.parabola.keyboardswitch.util.BigDecimalUtil;
import work.parabola.keyboardswitch.util.DateTimeUtil;

import java.math.BigDecimal;
import java.util.*;

@Service
public class PlateServiceImpl implements IPlateService {

    @Autowired
    private PlateDoMapper plateDoMapper;

    @Autowired
    private PlateCellDoMapper plateCellDoMapper;

    @Autowired
    private SwitchDoMapper switchDoMapper;

    @Autowired
    private SwitchTypeDoMapper switchTypeDoMapper;

    @Autowired
    private LoginUserDoMapper loginUserDoMapper;

    @Autowired
    private StoreSwitchDoMapper storeSwitchDoMapper;

    @Autowired
    private StoreSwitchOutputDoMapper storeSwitchOutputDoMapper;

    @Autowired
    private IStoreSwitchService iStoreSwitchService;

    @Override
    @Transactional
    public ServerResponse addTester(AddTesterQuery addTesterQuery, UserSession userSession) {
        if (addTesterQuery == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),
                    ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }
        int rowCount = this.plateDoMapper.selectCountByNameUserId(addTesterQuery.getName(), userSession.getId());
        if (rowCount > 0) {
            return ServerResponse.createByErrorMessage("试轴器名称重复");
        }
        PlateDo plateDo = new PlateDo();
        plateDo.setName(addTesterQuery.getName());
        plateDo.setType(PlateConst.PlateTypeEnum.TESTER.getCode());
        if (addTesterQuery.getOpen()) {
            plateDo.setOpen(PlateConst.PlateOpenEnum.OPEN.getCode());
        } else {
            plateDo.setOpen(PlateConst.PlateOpenEnum.NONOPEN.getCode());
        }
        plateDo.setRowCount(addTesterQuery.getRow());
        plateDo.setColCount(addTesterQuery.getCol());
        plateDo.setUserId(userSession.getId());
        rowCount = this.plateDoMapper.insertSelective(plateDo);
        if (rowCount == 0) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ServerResponse.createByErrorMessage("增加试轴器失败");
        }
        int totalCell = addTesterQuery.getRow() * addTesterQuery.getCol();
        List<PlateCellDo> plateCellDoList = new ArrayList<>(totalCell);
        for (int i = 0; i < totalCell; i++) {
            PlateCellDo plateCellDo = new PlateCellDo();
            plateCellDo.setPlateId(plateDo.getId());
            plateCellDo.setSequence(i);
            plateCellDo.setSwitchId(-1);
            plateCellDoList.add(plateCellDo);
        }
        rowCount = this.plateCellDoMapper.insertBatch(plateCellDoList);
        if (rowCount != totalCell) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ServerResponse.createByErrorMessage("增加试轴器失败");
        }
        return ServerResponse.createBySuccessMessage("增加试轴器成功");
    }

    @Override
    public ServerResponse getAdminTestList(ListQuery listQuery, UserSession userSession) {
        if (listQuery == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),
                    ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }
        ServerResponse response = listQuery.validate();
        if (!response.isSuccess()) {
            return response;
        }
        PageHelper.startPage(listQuery.getPageNum(), listQuery.getPageSize());
        List<PlateDo> plateDoList = this.plateDoMapper.selectByParam(listQuery.getKeyword(),
                PlateConst.PlateTypeEnum.TESTER.getCode(), null);
        List<PlateListVo> plateListVoList = new ArrayList<>();

        PageInfo pageResult = new PageInfo(plateDoList);
        for (PlateDo plateDo : plateDoList) {
            plateListVoList.add(this.assemblePlateListVo(plateDo));
        }
        pageResult.setList(plateListVoList);
        return ServerResponse.createBySuccess(pageResult);
    }

    private PlateListVo assemblePlateListVo(PlateDo plateDo) {
        PlateListVo vo = new PlateListVo();
        vo.setId(plateDo.getId());
        vo.setName(plateDo.getName());
        vo.setType(plateDo.getType());
        vo.setTypeName(PlateConst.PlateTypeEnum.codeOf(plateDo.getType()).getDesc());
        vo.setOpenDesc(PlateConst.PlateOpenEnum.codeOf(plateDo.getOpen()).getDesc());
        vo.setRowCount(plateDo.getRowCount());
        vo.setColCount(plateDo.getColCount());
        vo.setTotal(plateDo.getRowCount() * plateDo.getColCount());
        vo.setUserId(plateDo.getUserId());

        LoginUserDo loginUserDo = this.loginUserDoMapper.selectByPrimaryKey(plateDo.getUserId());
        vo.setUserName(loginUserDo.getName());
        vo.setCreateTime(DateTimeUtil.dateToStr(plateDo.getCreateTime(), DateTimeUtil.CH_MONTH_FORMAT));
        return vo;
    }

    @Override
    @Transactional
    public ServerResponse deleteAdminTester(UserSession userSession, Integer id) {
        if (id == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),
                    ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }
        PlateDo plateDo = this.plateDoMapper.selectByPrimaryKey(id);
        if (plateDo == null) {
            return ServerResponse.createByErrorMessage("试轴器不存在");
        }
        if (!plateDo.getType().equals(PlateConst.PlateTypeEnum.TESTER.getCode())) {
            return ServerResponse.createByErrorMessage("试轴器不存在");
        }
        this.plateDoMapper.deleteByPrimaryKey(id);
        this.plateCellDoMapper.deleteByPlateId(id);
        return ServerResponse.createBySuccessMessage("删除成功");
    }

    @Override
    public ServerResponse getAdminTesterDetail(UserSession userSession, Integer id) {
        if (id == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),
                    ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }
        PlateDo plateDo = this.plateDoMapper.selectByPrimaryKey(id);
        if (plateDo == null) {
            return ServerResponse.createByErrorMessage("试轴器不存在");
        }
        if (!plateDo.getType().equals(PlateConst.PlateTypeEnum.TESTER.getCode())) {
            return ServerResponse.createByErrorMessage("试轴器不存在");
        }
        return ServerResponse.createBySuccess(this.assembleTesterDetailVo(plateDo));
    }

    private TesterDetailVo assembleTesterDetailVo(PlateDo plateDo) {
        TesterDetailVo testerDetailVo = new TesterDetailVo();
        testerDetailVo.setPlateId(plateDo.getId());
        testerDetailVo.setName(plateDo.getName());
        testerDetailVo.setOpenDesc(PlateConst.PlateOpenEnum.codeOf(plateDo.getOpen()).getDesc());
        if (plateDo.getOpen().equals(PlateConst.PlateOpenEnum.OPEN.getCode())) {
            testerDetailVo.setOpen(true);
        } else {
            testerDetailVo.setOpen(false);
        }
        testerDetailVo.setRowCount(plateDo.getRowCount());
        testerDetailVo.setColCount(plateDo.getColCount());
        testerDetailVo.setUserId(plateDo.getUserId());
        testerDetailVo.setPrivilegeToEdit(true);
        LoginUserDo loginUserDo = this.loginUserDoMapper.selectByPrimaryKey(plateDo.getUserId());
        testerDetailVo.setUserName(loginUserDo.getName());
        testerDetailVo.setCreateTime(DateTimeUtil.dateToStr(plateDo.getCreateTime(), DateTimeUtil.CH_MONTH_FORMAT));
        testerDetailVo.setUpdateTime(DateTimeUtil.dateToStr(plateDo.getUpdateTime(), DateTimeUtil.CH_MONTH_FORMAT));
        List<CellVo> cellVoList = new ArrayList<>(plateDo.getRowCount() * plateDo.getColCount());
        testerDetailVo.setCellVoList(cellVoList);

        List<PlateCellDo> plateCellDoList = this.plateCellDoMapper.selectByPlateId(plateDo.getId());
        for (PlateCellDo plateCellDo : plateCellDoList) {
            CellVo cellVo = new CellVo();
            cellVo.setId(plateCellDo.getId());
            cellVo.setPlateId(plateCellDo.getPlateId());
            cellVo.setSequence(plateCellDo.getSequence());
            if (plateCellDo.getSwitchId().equals(-1)) {
                cellVo.setSwitchId(null);
                cellVo.setSimpleName("轴体未选择");
                cellVo.setBackgroundColor("ffffff");
                cellVo.setColor("000000");
                cellVo.setSalePrice("");
                cellVo.setSwitchId(-1);
                cellVo.setSwitchTypeName("");
            } else {
                cellVo.setSwitchId(plateCellDo.getSwitchId());
                SwitchDo switchDo = this.switchDoMapper.selectByPrimaryKey(plateCellDo.getSwitchId());
                cellVo.setSimpleName(switchDo.getSimpleName());
                cellVo.setBackgroundColor(switchDo.getBackgroundColor());
                cellVo.setColor(switchDo.getColor());
                cellVo.setSwitchTypeId(switchDo.getSwitchTypeId());
                cellVo.setSwitchTypeName(this.switchTypeDoMapper.selectByPrimaryKey(switchDo.getSwitchTypeId()).getName());
                StoreSwitchDo storeSwitchDo = this.storeSwitchDoMapper.selectBySwitchIdUserId(plateCellDo.getSwitchId(),
                        plateDo.getUserId());
                if (storeSwitchDo.getSalePrice() != null) {
                    cellVo.setSalePrice(storeSwitchDo.getSalePrice().toString());
                } else {
                    cellVo.setSalePrice("");
                }
            }
            cellVoList.add(cellVo);

        }
        return testerDetailVo;
    }

    @Override
    public ServerResponse editAdminTester(UserSession userSession, EditTesterQuery editTesterQuery) {
        if (editTesterQuery == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),
                    ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }
        ServerResponse response = editTesterQuery.validate();
        if (!response.isSuccess()) {
            return response;
        }
        PlateDo plateDo = this.plateDoMapper.selectByPrimaryKey(editTesterQuery.getPlateId());
        if (plateDo == null) {
            return ServerResponse.createByErrorMessage("试轴器不存在");
        }
        if (!plateDo.getType().equals(PlateConst.PlateTypeEnum.TESTER.getCode())) {
            return ServerResponse.createByErrorMessage("试轴器不存在");
        }
        PlateDo record = this.plateDoMapper.selectByNameUserId(editTesterQuery.getName(), plateDo.getUserId());
        if (record != null) {
            if (!record.getId().equals(plateDo.getId())) {
                return ServerResponse.createByErrorMessage("试轴器名称已经存在");
            }
        }
        PlateDo newRecord = new PlateDo();
        newRecord.setId(editTesterQuery.getPlateId());
        newRecord.setName(editTesterQuery.getName());
        if (editTesterQuery.getOpen()) {
            newRecord.setOpen(PlateConst.PlateOpenEnum.OPEN.getCode());
        } else {
            newRecord.setOpen(PlateConst.PlateOpenEnum.NONOPEN.getCode());
        }
        int rowCount = this.plateDoMapper.updateByPrimaryKeySelective(newRecord);
        if (rowCount == 0) {
            return ServerResponse.createByErrorMessage("修改失败");
        }
        return ServerResponse.createBySuccess();
    }

    @Override
    public ServerResponse setAdminTesterSwitch(SetTesterSwitchQuery setTesterSwitchQuery) {
        if (setTesterSwitchQuery == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),
                    ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }
        ServerResponse response = setTesterSwitchQuery.validate();
        if (!response.isSuccess()) {
            return response;
        }
        PlateCellDo plateCellDo = this.plateCellDoMapper.selectByPrimaryKey(setTesterSwitchQuery.getCellId());
        if (plateCellDo == null) {
            return ServerResponse.createByErrorMessage("试轴器不存在");
        }
        SwitchDo switchDo = this.switchDoMapper.selectByPrimaryKey(setTesterSwitchQuery.getSwitchId());
        if (switchDo == null) {
            return ServerResponse.createByErrorMessage("要设置的轴体不存在");
        }
        PlateCellDo updateRecord = new PlateCellDo();
        updateRecord.setId(setTesterSwitchQuery.getCellId());
        updateRecord.setSwitchId(setTesterSwitchQuery.getSwitchId());
        int rowCount = this.plateCellDoMapper.updateByPrimaryKeySelective(updateRecord);
        if (rowCount == 0) {
            return ServerResponse.createByErrorMessage("设置轴体失败");
        }
        return ServerResponse.createBySuccessMessage("设置轴体成功");
    }

    @Override
    public ServerResponse emptyAdminTesterSwitch(Integer cellId) {
        if (cellId == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),
                    ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }
        PlateCellDo plateCellDo = this.plateCellDoMapper.selectByPrimaryKey(cellId);
        if (plateCellDo == null) {
            return ServerResponse.createByErrorMessage("试轴器格子不存在");
        }
        PlateCellDo updateRecord = new PlateCellDo();
        updateRecord.setId(plateCellDo.getId());
        updateRecord.setSwitchId(-1);
        int rowCount = this.plateCellDoMapper.updateByPrimaryKeySelective(updateRecord);
        if (rowCount == 0) {
            return ServerResponse.createByErrorMessage("删除试轴器格子失败");
        }

        return ServerResponse.createBySuccessMessage("清除成功");
    }

    @Override
    @Transactional
    public ServerResponse emptyAdminTesterSwitchRow(Integer cellId) {
        if (cellId == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),
                    ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }
        PlateCellDo plateCellDo = this.plateCellDoMapper.selectByPrimaryKey(cellId);
        if (plateCellDo == null) {
            return ServerResponse.createByErrorMessage("试轴器格子不存在");
        }
        PlateDo plateDo = this.plateDoMapper.selectByPrimaryKey(plateCellDo.getPlateId());
        //计算轴体所在第几行
        int row = plateCellDo.getSequence() / plateDo.getColCount();
        //计算这一行所有轴的序列号
        int indexStart = row * plateDo.getColCount();
        int indexEnd = indexStart + plateDo.getColCount() - 1;

        PlateCellDo updateRecord = new PlateCellDo();
        updateRecord.setPlateId(plateDo.getId());
        updateRecord.setSwitchId(-1);

        for (int i = indexStart; i <= indexEnd; i++) {
            updateRecord.setSequence(i);
            int rowCount = this.plateCellDoMapper.updateByPlateIdSequenceId(updateRecord);
            if (rowCount == 0) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ServerResponse.createByErrorMessage("清除轴体失败");
            }
        }
        return ServerResponse.createBySuccessMessage("清除成功");
    }

    @Override
    @Transactional
    public ServerResponse emptyAdminTesterSwitchCol(Integer cellId) {
        if (cellId == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),
                    ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }
        PlateCellDo plateCellDo = this.plateCellDoMapper.selectByPrimaryKey(cellId);
        if (plateCellDo == null) {
            return ServerResponse.createByErrorMessage("试轴器格子不存在");
        }
        PlateDo plateDo = this.plateDoMapper.selectByPrimaryKey(plateCellDo.getPlateId());
        //计算轴体在第几列
        int col = plateCellDo.getSequence() % plateDo.getColCount();
        int total = plateDo.getRowCount() * plateDo.getColCount();

        PlateCellDo updateRecord = new PlateCellDo();
        updateRecord.setPlateId(plateDo.getId());
        updateRecord.setSwitchId(-1);
        for (int i = col; i < total; i += plateDo.getColCount()) {
            updateRecord.setSequence(i);
            int rowCount = this.plateCellDoMapper.updateByPlateIdSequenceId(updateRecord);
            if (rowCount == 0) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ServerResponse.createByErrorMessage("清除轴体失败");
            }
        }
        return ServerResponse.createBySuccessMessage("清除成功");
    }

    @Override
    @Transactional
    public ServerResponse forwardAdminTesterSwitch(Integer cellId) {
        if (cellId == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),
                    ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }
        PlateCellDo plateCellDo = this.plateCellDoMapper.selectByPrimaryKey(cellId);
        if (plateCellDo == null) {
            return ServerResponse.createByErrorMessage("试轴器格子不存在");
        }
        List<PlateCellDo> plateCellDoList = this.plateCellDoMapper.selectByPlateId(plateCellDo.getPlateId());
        if (plateCellDo.getSequence().equals(plateCellDoList.size() - 1)) {
            return ServerResponse.createByErrorMessage("该试轴器格子已经是最后一个了，无法后移");
        }
        if (!plateCellDoList.get(plateCellDoList.size() - 1).getSwitchId().equals(-1)) {
            return ServerResponse.createByErrorMessage("试轴器最后一个格已经设置轴体，后移将导致轴体消失，无法后移");
        }
        for (int i = plateCellDoList.size() - 1; plateCellDo.getSequence().compareTo(i) < 0; i--) {
            PlateCellDo updateRecord = new PlateCellDo();
            PlateCellDo prePlateCellDo = plateCellDoList.get(i - 1);
            updateRecord.setId(plateCellDoList.get(i).getId());
            updateRecord.setSwitchId(prePlateCellDo.getSwitchId());
            this.plateCellDoMapper.updateByPrimaryKeySelective(updateRecord);
        }
        this.emptyAdminTesterSwitch(cellId);
        return ServerResponse.createBySuccessMessage("后移成功");
    }

    @Override
    @Transactional
    public ServerResponse backwardAdminTesterSwitch(Integer cellId) {
        if (cellId == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),
                    ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }
        PlateCellDo plateCellDo = this.plateCellDoMapper.selectByPrimaryKey(cellId);
        if (plateCellDo == null) {
            return ServerResponse.createByErrorMessage("试轴器格子不存在");
        }
        if (plateCellDo.getSequence().equals(0)) {
            return ServerResponse.createByErrorMessage("试轴器格子已经是第1个，无法前移");
        }
        List<PlateCellDo> plateCellDoList = this.plateCellDoMapper.selectByPlateId(plateCellDo.getPlateId());
        if (!plateCellDoList.get(plateCellDo.getSequence() - 1).getSwitchId().equals(-1)) {
            return ServerResponse.createByErrorMessage("前一格已放置轴体，无法前移");
        }
        for (int i = plateCellDo.getSequence() - 1; i < plateCellDoList.size() - 1; i++) {
            PlateCellDo nextPlateCellDo = plateCellDoList.get(i + 1);
            PlateCellDo updateRecord = new PlateCellDo();
            updateRecord.setId(plateCellDoList.get(i).getId());
            updateRecord.setSwitchId(nextPlateCellDo.getSwitchId());
            this.plateCellDoMapper.updateByPrimaryKeySelective(updateRecord);
        }
        this.emptyAdminTesterSwitch(plateCellDoList.get(plateCellDoList.size() - 1).getId());
        return ServerResponse.createBySuccessMessage("前移成功");
    }

    @Override
    public ServerResponse calAdminTesterPrice(Integer id, UserSession userSession) {
        if (id == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),
                    ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }
        //获取试轴器中的所有的轴
        List<PlateCellDo> plateCellDoList = this.plateCellDoMapper.selectByPlateId(id);
        if (plateCellDoList.size() == 0) {
            return ServerResponse.createByErrorMessage("试轴器不存在");
        }
        //取得保存的所有轴体清单
        List<StoreSwitchDo> storeSwitchDoList = this.storeSwitchDoMapper.selectByParams(
                null, userSession.getId(), null, null);
        Map<Integer, StoreSwitchDo> storeSwitchDoMap = new HashMap<>();
        for (StoreSwitchDo storeSwitchDo : storeSwitchDoList) {
            storeSwitchDoMap.put(storeSwitchDo.getSwitchId(), storeSwitchDo);
        }

        Map<Integer, Integer> plateCellMap = new HashMap<>();
        for (PlateCellDo plateCellDo : plateCellDoList) {
            if (plateCellDo.getSwitchId() == null || plateCellDo.getSwitchId().equals(-1)) {
                continue;
            }
            if (plateCellMap.containsKey(plateCellDo.getSwitchId())) {
                Integer amount = plateCellMap.get(plateCellDo.getSwitchId());
                amount = amount + 1;
                plateCellMap.put(plateCellDo.getSwitchId(), amount);
            } else {
                plateCellMap.put(plateCellDo.getSwitchId(), 1);
            }
        }

        BigDecimal totalPrice = BigDecimalUtil.ZERO_SCALE_2;
        BigDecimal totalSalePrice = BigDecimalUtil.ZERO_SCALE_2;
        Integer totalCount = 0;
        List<String> errorList = new ArrayList<>();
        List<String> noStoreList = new ArrayList<>();
        PlatePriceVo platePriceVo = new PlatePriceVo();

        for (Map.Entry<Integer, Integer> item : plateCellMap.entrySet()) {
            StoreSwitchDo storeSwitchDo = storeSwitchDoMap.get(item.getKey());
            if (storeSwitchDo == null || storeSwitchDo.getPrice().equals(BigDecimalUtil.ZERO_SCALE_2) ||
                    storeSwitchDo.getSalePrice() == null || storeSwitchDo.getSalePrice().equals(BigDecimalUtil.ZERO_SCALE_2)) {
                errorList.add(this.switchDoMapper.selectByPrimaryKey(storeSwitchDo.getSwitchId()).getSimpleName());
                continue;
            }
            if (storeSwitchDo.getAmount().compareTo(item.getValue()) < 0) {
                noStoreList.add(this.switchDoMapper.selectByPrimaryKey(storeSwitchDo.getSwitchId()).getSimpleName());
                continue;
            }
            totalPrice = BigDecimalUtil.add(totalPrice,
                    BigDecimalUtil.mulInt(storeSwitchDo.getPrice(), item.getValue(), 2), 2);
            totalSalePrice = BigDecimalUtil.add(totalSalePrice,
                    BigDecimalUtil.mulInt(storeSwitchDo.getSalePrice(), item.getValue(), 2), 2);
            totalCount += item.getValue();
        }
        platePriceVo.setTotalPrice(totalPrice);
        platePriceVo.setTotalCount(totalCount);
        platePriceVo.setTotalSalePrice(totalSalePrice);
        platePriceVo.setNoPriceSwitchList(errorList);
        platePriceVo.setNoStoreSwitchList(noStoreList);
        return ServerResponse.createBySuccess(platePriceVo);
    }

    @Override
    @Transactional
    public ServerResponse autoChooseAdminTester(Integer plateId) {
        if (plateId == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),
                    ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }
        PlateDo plateDo = this.plateDoMapper.selectByPrimaryKey(plateId);
        if (plateDo == null) {
            return ServerResponse.createByErrorMessage("试轴器不存在");
        }
        List<SwitchDo> switchDoList = this.switchDoMapper.selectByParam(null,
                false, false);
        Map<Integer, SwitchDo> switchDoMap = new HashMap<>();
        for (SwitchDo switchDo : switchDoList) {
            switchDoMap.put(switchDo.getId(), switchDo);
        }
        List<PlateCellDo> plateCellDoList = this.plateCellDoMapper.selectByPlateId(plateId);
        for (PlateCellDo plateCellDo : plateCellDoList) {
            if (plateCellDo.getSwitchId().equals(-1)) {
                continue;
            }
            if (switchDoMap.containsKey(plateCellDo.getSwitchId())) {
                switchDoMap.remove(plateCellDo.getSwitchId());
            }
        }
        for (PlateCellDo plateCellDo : plateCellDoList) {
            if (switchDoMap.size() == 0) {
                break;
            }
            if (!plateCellDo.getSwitchId().equals(-1)) {
                //已选择轴体
                continue;
            }
            //从map中随机选择一个
            Integer[] keys = switchDoMap.keySet().toArray(new Integer[0]);
            Random random = new Random();
            Integer randomSwitchId = keys[random.nextInt(keys.length)];
            PlateCellDo updateRecord = new PlateCellDo();
            updateRecord.setId(plateCellDo.getId());
            updateRecord.setSwitchId(randomSwitchId);
            int rowCount = this.plateCellDoMapper.updateByPrimaryKeySelective(updateRecord);
            if (rowCount == 0) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ServerResponse.createByErrorMessage("自动生成轴体失败");
            }
            switchDoMap.remove(randomSwitchId);
        }
        return ServerResponse.createBySuccessMessage("自动成生试轴器成功");

    }

    @Override
    @Transactional
    public ServerResponse autoAdminProduceTester(AutoProduceTesterQuery autoProduceTesterQuery, UserSession userSession) {
        ServerResponse response = autoProduceTesterQuery.validate();
        if (!response.isSuccess()) {
            return response;
        }
        work.parabola.keyboardswitch.pojo.query.storeswitch.ListQuery storeSwitchListQuery =
                new work.parabola.keyboardswitch.pojo.query.storeswitch.ListQuery();

        storeSwitchListQuery.setSearchWord(autoProduceTesterQuery.getSearchWord());
        storeSwitchListQuery.setSwitchType(autoProduceTesterQuery.getSwitchType());
        storeSwitchListQuery.setOrderByAmount(autoProduceTesterQuery.getOrderByAmount());
        storeSwitchListQuery.setOrderByPrice(autoProduceTesterQuery.getOrderByPrice());

        response = storeSwitchListQuery.validate();
        if (!response.isSuccess()) {
            return response;
        }
        response = this.iStoreSwitchService.getAdminSwitchStoreList(storeSwitchListQuery, userSession);
        if (!response.isSuccess()) {
            return response;
        }
        //根据筛选条件查询了所有库存轴体列表
        List<StoreSwitchListVo> storeSwitchListVoList = (List<StoreSwitchListVo>) response.getData();


        //根据行数和列数创建试轴器
        PlateDo plateDo = new PlateDo();
        plateDo.setName(String.format("%s-自动创建-%s",
                DateTimeUtil.dateToStr(new Date(), DateTimeUtil.FULL_FORMAT),
                UUID.randomUUID()));
        plateDo.setType(PlateConst.PlateTypeEnum.TESTER.getCode());
        plateDo.setOpen(PlateConst.PlateOpenEnum.NONOPEN.getCode());
        plateDo.setRowCount(autoProduceTesterQuery.getRow());
        plateDo.setColCount(autoProduceTesterQuery.getCol());
        plateDo.setUserId(userSession.getId());
        int rowCount = this.plateDoMapper.insertSelective(plateDo);
        if (rowCount == 0) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ServerResponse.createByErrorMessage("自动生成试轴器失败");
        }
        List<Integer> list = new ArrayList<>();
        for (StoreSwitchListVo storeSwitchListVo : storeSwitchListVoList) {
            if (storeSwitchListVo.getAmount().compareTo(0) <= 0) {
                continue;
            }
            list.add(storeSwitchListVo.getSwitchId());
        }

        int cellCount = autoProduceTesterQuery.getRow() * autoProduceTesterQuery.getCol();
        for (int i = 0; i < cellCount; i++) {
            PlateCellDo plateCellDo = new PlateCellDo();
            plateCellDo.setPlateId(plateDo.getId());
            plateCellDo.setSequence(i);
            if (list.size() < i + 1) {
                plateCellDo.setSwitchId(-1);
            } else {
                plateCellDo.setSwitchId(list.get(i));
            }
            rowCount = this.plateCellDoMapper.insertSelective(plateCellDo);
            if (rowCount == 0) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ServerResponse.createByErrorMessage("自动生成试轴器失败");
            }
        }
        return ServerResponse.createBySuccessMessage("自动生成试轴器成功");
    }

    @Override
    @Transactional
    public ServerResponse resizeAdminTester(ResizeQuery resizeQuery) {
        if (resizeQuery == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),
                    ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }
        ServerResponse response = resizeQuery.validate();
        if (!response.isSuccess()) {
            return response;
        }
        PlateDo plateDo = this.plateDoMapper.selectByPrimaryKey(resizeQuery.getId());
        if (plateDo == null || plateDo.getType() != PlateConst.PlateTypeEnum.TESTER.getCode()) {
            return ServerResponse.createByErrorMessage("试轴器不存在");
        }
        PlateDo updateRecord = new PlateDo();
        updateRecord.setId(resizeQuery.getId());
        updateRecord.setRowCount(resizeQuery.getRow());
        updateRecord.setColCount(resizeQuery.getCol());
        this.plateDoMapper.updateByPrimaryKeySelective(updateRecord);

        int originSize = plateDo.getRowCount() * plateDo.getColCount();
        int size = resizeQuery.getRow() * resizeQuery.getCol();
        if (size > originSize) {
            //增加尺寸
            List<PlateCellDo> plateCellDoList = new ArrayList<>();
            for (int i = originSize; i < size; i++) {
                PlateCellDo plateCellDo = new PlateCellDo();
                plateCellDo.setPlateId(resizeQuery.getId());
                plateCellDo.setSequence(i);
                plateCellDo.setSwitchId(-1);
                plateCellDoList.add(plateCellDo);
            }
            int rowCount = this.plateCellDoMapper.insertBatch(plateCellDoList);
            if (rowCount == 0) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        } else if (size < originSize) {
            //缩小尺寸
            List<PlateCellDo> plateCellDoList = this.plateCellDoMapper.selectByPlateId(resizeQuery.getId());
            for (int i = size; i < originSize; i++) {
                if (!plateCellDoList.get(i).getSwitchId().equals(-1)) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return ServerResponse.createByErrorMessage("试轴器尺寸缩小失败");
                }
            }
            for (int i = size; i < originSize; i++) {
                this.plateCellDoMapper.deleteByPrimaryKey(plateCellDoList.get(i).getId());
            }
        }

        return ServerResponse.createBySuccessMessage("修改大小成功");
    }

    @Override
    @Transactional
    public ServerResponse checkoutAdminTester(Integer id, UserSession userSession) {
        ServerResponse response = this.calAdminTesterPrice(id, userSession);
        if (!response.isSuccess()) {
            return response;
        }
        PlatePriceVo platePriceVo = (PlatePriceVo) response.getData();
        if (platePriceVo.getNoPriceSwitchList().size() != 0 || platePriceVo.getNoStoreSwitchList().size() != 0) {
            return ServerResponse.createByErrorMessage("部分轴体无价格或者无库存，无法出库");
        }
        List<PlateCellDo> plateCellDoList = this.plateCellDoMapper.selectByPlateId(id);
        List<StoreSwitchDo> storeSwitchDoList = this.storeSwitchDoMapper.selectByParams(null, userSession.getId(),
                false, false);
        Map<Integer, StoreSwitchDo> storeSwitchMap = new HashMap<>();
        for (StoreSwitchDo storeSwitchDo : storeSwitchDoList) {
            storeSwitchMap.put(storeSwitchDo.getSwitchId(), storeSwitchDo);
        }
        Map<Integer, Integer> plateCellMap = new HashMap<>();
        for (PlateCellDo plateCellDo : plateCellDoList) {
            if (plateCellDo.getSwitchId() == null || plateCellDo.getSwitchId().equals(-1)) {
                continue;
            }
            if (plateCellMap.containsKey(plateCellDo.getSwitchId())) {
                Integer amount = plateCellMap.get(plateCellDo.getSwitchId());
                amount = amount + 1;
                plateCellMap.put(plateCellDo.getSwitchId(), amount);
            } else {
                plateCellMap.put(plateCellDo.getSwitchId(), 1);
            }
        }
        for (Map.Entry<Integer, Integer> item : plateCellMap.entrySet()) {
            StoreSwitchDo storeSwitchDo = storeSwitchMap.get(item.getKey());
            StoreSwitchDo updateRecord = new StoreSwitchDo();
            updateRecord.setId(storeSwitchDo.getId());
            updateRecord.setAmount(storeSwitchDo.getAmount() - item.getValue());
            this.storeSwitchDoMapper.updateByPrimaryKeySelective(updateRecord);
            StoreSwitchOutputDo storeSwitchOutputDo = new StoreSwitchOutputDo();
            storeSwitchOutputDo.setSwitchId(storeSwitchDo.getSwitchId());
            storeSwitchOutputDo.setAmount(item.getValue());
            storeSwitchOutputDo.setStoreSwitchId(storeSwitchDo.getId());
            storeSwitchOutputDo.setUserId(userSession.getId());
            this.storeSwitchOutputDoMapper.insertSelective(storeSwitchOutputDo);
        }

        return ServerResponse.createBySuccessMessage("出库成功");
    }

    @Override
    public ServerResponse showListAdminTester(Integer id, UserSession userSession) {
        if (id == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),
                    ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }
        PlateDo plateDo = this.plateDoMapper.selectByPrimaryKey(id);
        if (plateDo == null || plateDo.getType() != PlateConst.PlateTypeEnum.TESTER.getCode()) {
            return ServerResponse.createByErrorMessage("试轴器不存在");
        }
        List<PlateCellDo> plateCellDoList = this.plateCellDoMapper.selectByPlateId(id);
        Map<Integer, Integer> map = new HashMap<>();
        for (PlateCellDo plateCellDo : plateCellDoList) {
            if (plateCellDo.getSwitchId().compareTo(-1) == 0) {
                continue;
            }
            if (map.containsKey(plateCellDo.getSwitchId())) {
                Integer amount = map.get(plateCellDo.getSwitchId());
                map.put(plateCellDo.getSwitchId(), amount + 1);
            } else {
                map.put(plateCellDo.getSwitchId(), 1);
            }
        }
        Map<Integer, StoreSwitchDo> storeMap = new HashMap<>();
        List<StoreSwitchDo> storeSwitchDoList = this.storeSwitchDoMapper.selectByParams(null,
                userSession.getId(), false, false);
        for (StoreSwitchDo storeSwitchDo : storeSwitchDoList) {
            storeMap.put(storeSwitchDo.getSwitchId(), storeSwitchDo);
        }
        List<TesterSwitchVo> testerSwitchVoList = new ArrayList<>();
        for (PlateCellDo plateCellDo : plateCellDoList) {
            if (!map.containsKey(plateCellDo.getSwitchId())) {
                continue;
            }

            TesterSwitchVo testerSwitchVo = new TesterSwitchVo();
            testerSwitchVo.setSwitchId(plateCellDo.getSwitchId());
            testerSwitchVo.setAmount(map.get(plateCellDo.getSwitchId()));
            testerSwitchVo.setSwitchSimpleName(this.switchDoMapper.selectByPrimaryKey(plateCellDo.getSwitchId()).getSimpleName());
            testerSwitchVo.setNote(storeMap.get(plateCellDo.getSwitchId()).getNote());
            map.remove(plateCellDo.getSwitchId());
            testerSwitchVoList.add(testerSwitchVo);
        }

        return ServerResponse.createBySuccess(testerSwitchVoList);
    }

    @Override
    @Transactional
    public ServerResponse autoAdminPlaceTester(Integer id, UserSession userSession) {
        if (id == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(), ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }
        PlateDo plateDo = this.plateDoMapper.selectByPrimaryKey(id);
        if (plateDo == null || plateDo.getType().compareTo(PlateConst.PlateTypeEnum.TESTER.getCode()) != 0) {
            return ServerResponse.createByErrorMessage("试轴器不存在");
        }
        List<PlateCellDo> plateCellDoList = this.plateCellDoMapper.selectByPlateId(id);
        List<Integer> originSwitchIdList = new ArrayList<>();
        for (PlateCellDo plateCellDo : plateCellDoList) {
            if (plateCellDo.getSwitchId().equals(-1)) {
                continue;
            }
            originSwitchIdList.add(plateCellDo.getSwitchId());
        }
        for (int i = 0; i < plateCellDoList.size(); i++) {
            PlateCellDo plateCellDo = plateCellDoList.get(i);
            if (i < originSwitchIdList.size()) {
                plateCellDo.setSwitchId(originSwitchIdList.get(i));
                continue;
            }
            plateCellDo.setSwitchId(-1);
        }
        this.plateCellDoMapper.deleteByPlateId(id);
        this.plateCellDoMapper.insertBatch(plateCellDoList);
        return ServerResponse.createBySuccessMessage("试轴器重新排列成功");
    }
}
